/*
 * Copyright (C) 2024 ~ 2025 Deepin Technology Co., Ltd.
 *
 * Author:     zhangbingyi <zhangbingyi@uniontech.com>
 *
 * Maintainer: zhangbingyi <zhangbingyi@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "homepagemodel.h"
#include "comdata.h"
#include "invokers/invokerfactory.h"
#include "gsettingkey.h"
//#include <QGSettings>
//#include <QStorageInfo>
#include "antivirus/antiviruswork.h"
#include <QDebug>
#include <QApplication>
#include <QProcess>
//#include <QtConcurrent>

#define DIALOG_WIDTH 380 //dialog  宽度
#define DIALOG_HEIGHT 145 //dialog  高度

//DWIDGET_USE_NAMESPACE

HomePageModel::HomePageModel(QObject *parent)
    : QObject(parent)
    , m_gSettingsInvokerInter(nullptr)
    , m_defenderDataInvokerInter(nullptr)
    , m_controlCenterInvokerInter(nullptr)
    , m_helperInvokerInter(nullptr)
    , m_diskManagerInvokerInter(nullptr)
    , m_netFlowMonitorInvokerInter(nullptr)
    , m_antiVirusWork(nullptr)
    , m_sysUpdaterModel(nullptr)
    , m_virusScanning(false)
    , m_virusPathList({})
    , m_vdbChecking(false)
    , m_autoStartAppChecking(false)
    , m_sysVersionChecking(false)
    , m_trashChecking(false)
    , m_diskChecking(false)
    , m_developModeChecking(false)
{
    //使用GSetting读取参数
    m_gSettingsInvokerInter = InvokerFactory::GetInstance().CreateSettings("com.deepin.dde.deepin-defender", QByteArray(), this);
    m_defenderDataInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.datainterface",
                                                                             "/com/deepin/defender/datainterface",
                                                                             "com.deepin.defender.datainterface",
                                                                             ConnectType::SESSION, this);
    // 控制中心dbus服务对象
    m_controlCenterInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.dde.ControlCenter",
                                                                              "/com/deepin/dde/ControlCenter",
                                                                              "com.deepin.dde.ControlCenter",
                                                                              ConnectType::SESSION, this);
    // 安全中心dbus服务对象
    m_defenderWindowInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.hmiscreen",
                                                                               "/com/deepin/defender/hmiscreen",
                                                                               "com.deepin.defender.hmiscreen",
                                                                               ConnectType::SESSION, this);
    // 同步助手dbus服务，用于查询是否处于开发者模式
    m_helperInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.sync.Helper",
                                                                       "/com/deepin/sync/Helper",
                                                                       "com.deepin.sync.Helper",
                                                                       ConnectType::SYSTEM, this);
    // 磁盘管理dbus服务
    m_diskManagerInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.diskmanager",
                                                                            "/com/deepin/diskmanager",
                                                                            "com.deepin.diskmanager",
                                                                            ConnectType::SYSTEM, this);
    // 流量监控系统dbus服务
    m_netFlowMonitorInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.defender.MonitorNetFlow",
                                                                               "/com/deepin/defender/MonitorNetFlow",
                                                                               "com.deepin.defender.MonitorNetFlow",
                                                                               ConnectType::SYSTEM, this);
    // 系统语言选择器dbus服务
    m_langSelectInvokerInter = InvokerFactory::GetInstance().CreateInvoker("com.deepin.daemon.LangSelector",
                                                                           "/com/deepin/daemon/LangSelector",
                                                                           "com.deepin.daemon.LangSelector",
                                                                           ConnectType::SESSION, this);

    // 系统更新数据处理对象
    m_sysUpdaterModel = new SysUpdaterModel(this);

    // 预启动磁盘管理器服务，避免磁盘检测时调用接口卡顿
    DBUS_NOBLOCK_INVOKE(m_diskManagerInvokerInter, "Start");

    SetAntiVirusWork(new AntiVirusWork(this));
}

// 设置上次体检分数
void HomePageModel::setSafetyScore(const int &score)
{
    m_gSettingsInvokerInter->SetValue(SAFETY_SCORE, score);
}

// 获取上次体检分数
int HomePageModel::GetSafetyScore()
{
    return m_gSettingsInvokerInter->GetValue(SAFETY_SCORE).toInt();
}

// 设置上次体检时间
void HomePageModel::SetLastCheckTime(QDateTime dateTime)
{
    m_gSettingsInvokerInter->SetValue(LAST_CHECK_TIME, dateTime.toString("yyyy-MM-dd-hh-mm-ss"));
}

// 获取上次体检时间
QDateTime HomePageModel::GetLastCheckTime()
{
    QString timeStr = m_gSettingsInvokerInter->GetValue(LAST_CHECK_TIME).toString();
    return QDateTime::fromString(timeStr, "yyyy-MM-dd-hh-mm-ss");
}

// 获取当前病毒查杀服务扫描状态
ScanStatus HomePageModel::scanStatus()
{
    return m_antiVirusWork->getCurrentScanStatus();
}

// 是否正在检测病毒库更新
bool HomePageModel::vdbUpdataChecking()
{
    return m_antiVirusWork->vdbVersionChecking();
}

// 是否正在操作隔离或信任区文件
bool HomePageModel::isOperatingIsolateTrustFiles()
{
    return m_antiVirusWork->isOperatingIsolateTrustFiles();
}

void HomePageModel::SetAntiVirusWork(AntiVirusWork *work)
{
    m_antiVirusWork = work;
    //// 病毒查杀
    // 接收来自病毒扫描控制器的扫描结果
    connect(m_antiVirusWork, SIGNAL(sendResultWhileScanFinished(QStringList)), this, SLOT(RecResultWhileScanFinished(QStringList)));
    // 连接修复问题文件结果信号
    connect(m_antiVirusWork, SIGNAL(sendRepairProblemFileResult(QString)), this, SLOT(RecRepairProblemFileResult(QString)));
    //// 病毒库版本
    // 通知去检查病毒库版本
    connect(this, SIGNAL(NotifyCheckVdbVersion()), m_antiVirusWork, SLOT(queryVersionStatus()));
    // 检查病毒库版本完成
    connect(m_antiVirusWork, SIGNAL(haveNewVdb(bool)), this, SIGNAL(CheckVdbFinished(bool)));
    // 通知去更新病毒库
    connect(this, SIGNAL(NotifyUpdateVdb()), m_antiVirusWork, SLOT(requestUpdateVirusDb()));
    // 更新病毒库完成
    connect(m_antiVirusWork, SIGNAL(updateVdbFinished(bool)), this, SIGNAL(UpdateVdbFinished(bool)));
    //// 自启动
    // 更新自启动应用个数
    m_defenderDataInvokerInter->Connect("AccessRefreshData", this, SLOT(updateStartUpAppCount(bool, QString)));
    //// ssh
    // 当ssh状态改变时
    m_netFlowMonitorInvokerInter->Connect("SendSSHStatus", this, SIGNAL(sendSSHStatus(bool)));
    //// 系统版本
    // 通知去检查系统更新
    connect(this, SIGNAL(NotifyCheckSysUpdate()), m_sysUpdaterModel, SLOT(CheckForUpdates()));
    // 通知去停止检查系统更新
    connect(this, SIGNAL(notifyStopCheckSysUpdate()), m_sysUpdaterModel, SLOT(stopCheckingSysVer()));
    // 检查系统更新完成
    connect(m_sysUpdaterModel, SIGNAL(SendHaveUpdates(bool)), this, SIGNAL(CheckSysUpdateFinished(bool)));
    /// 垃圾清理
    // 请求开始垃圾文件扫描
    connect(this, SIGNAL(requestStartTrashScan()), this, SLOT(onRequestStartTrashScan()));

    // 垃圾文件扫描完成时
    m_defenderDataInvokerInter->Connect("TrashScanFinished", this, SIGNAL(trashScanFinished(double)));
    // 请求清理选中的垃圾文件
    connect(this, SIGNAL(requestCleanSelectTrash()), this, SLOT(onRequestCleanSelectTrash()));
    // 清理选中的垃圾文件完成时
    m_defenderDataInvokerInter->Connect("CleanSelectTrashFinished", this, SIGNAL(cleanSelectTrashFinished()));
}

void HomePageModel::openStartupControlPage()
{
    DBUS_BLOCK_INVOKE(m_defenderWindowInvokerInter, "ShowPage", MODULE_SECURITY_TOOLS_NAME, STARTUP_CONTROL_NAME);
    addSecurityLog(tr("Startup programs checked"));
}

// 打开系统更新界面
void HomePageModel::openSysUpdatePage()
{
    DBUS_NOBLOCK_INVOKE(m_controlCenterInvokerInter, "Show");
    DBUS_NOBLOCK_INVOKE(m_controlCenterInvokerInter, "ShowPage", "update", "");
    addSecurityLog(tr("System updated"));
}

// 磁盘管理器 是否已安装
bool HomePageModel::isDiskManagerInterValid()
{
    QProcess proc;
    // 查询是否已经安装 磁盘管理器
    proc.start("dpkg -s deepin-diskmanager");
    proc.waitForFinished();
    QString status = proc.readAllStandardOutput();

    // 若返回结果以 "Package: deepin-diskmanager\nStatus: install"，则说明已安装
    return status.startsWith("Package: deepin-diskmanager\nStatus: install");
}

// 获取磁盘状态
bool HomePageModel::getDiskStatus()
{
    // 遍历所有磁盘设备路径
    QDBusMessage msg;
    msg = DBUS_BLOCK_INVOKE(m_netFlowMonitorInvokerInter, "GetDiskDevicePathList");
    GET_MESSAGE_VALUE(QStringList, devPaths, msg);

    for (QString devPath : devPaths) {
        msg = DBUS_BLOCK_INVOKE(m_diskManagerInvokerInter, "onGetDeviceHardStatus", devPath);
        GET_MESSAGE_VALUE(QString, data, msg);

        // 状态结果转小写
        QString status = data.toLower();
        // 若状态为异常，返回false
        if ("passed" != status) {
            return false;
        }
    }

    // 所有磁盘正常
    return true;
}

// 是否处于开发者模式
bool HomePageModel::IsDeveloperMode()
{
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_helperInvokerInter, "IsDeveloperMode");
    GET_MESSAGE_VALUE(bool, rst, msg);

    return rst;
}

bool HomePageModel::ignoreDevModeChecking() const
{
    // 服务器版差异修改
//    if (DSysInfo::UosType::UosServer == SystemType) {
//        return true;
//    }

    return m_gSettingsInvokerInter->GetValue(IGNORE_DEV_MODE_CHECKING).toBool();
}

void HomePageModel::setIgnoreDevModeChecking(bool ignore)
{
    m_gSettingsInvokerInter->SetValue(IGNORE_DEV_MODE_CHECKING, ignore);
}

QString HomePageModel::getLocalLang()
{
    QString lang;
    QVariantList args = DBUS_BLOCK_INVOKE(m_langSelectInvokerInter, DBUS_PROPERTY_INVOKER_NAME, "CurrentLocale").arguments();
    if (args.isEmpty()) {
        return lang;
    }
    lang = Utils::checkAndTransQDbusVarIntoQVar(args.first()).toString();

    return lang;
}

void HomePageModel::doHomepageVirusScan()
{
    m_antiVirusWork->setCurrentScanStatus(ScanStatus::HomePageScanning);
    m_antiVirusWork->doQuickScan();
}

// 当扫描结束发出扫描结果时
void HomePageModel::RecResultWhileScanFinished(QStringList list)
{
    // 当前处于首页病毒查杀状态，才进行处理
    if (ScanStatus::HomePageScanning != m_antiVirusWork->getCurrentScanStatus()) {
        return;
    }

    m_virusPathList = list;
    if (0 == m_virusPathList.count()) {
        // 当扫描结果无病毒，设置病毒扫描状态为空闲
        m_antiVirusWork->setCurrentScanStatus(ScanStatus::Free);
    } else {
        // 当扫描结果存在病毒，设置病毒扫描状态为处于 “首页病毒扫描结果”
        m_antiVirusWork->setCurrentScanStatus(ScanStatus::HomePageResult);
    }
    // 发送首页扫描完成信号
    Q_EMIT homepageVirusScanFinished(m_virusPathList);
}

// 当接收到修复问题文件结果时
void HomePageModel::RecRepairProblemFileResult(QString sPath)
{
    // 当处于 首页扫描结果 时，才进行首页扫描病毒列表更新
    ScanStatus status = m_antiVirusWork->getCurrentScanStatus();
    if (ScanStatus::HomePageFixing == status || ScanStatus::VdbUpdating == status || ScanStatus::Free == status) {
        // 从问题文件列表中移除已修复的文件
        m_virusPathList.removeOne(sPath);
        // 若问题文件列表为空，发送修复完成信号
        if (m_virusPathList.isEmpty()) {
            Q_EMIT this->HomepageVirusScanResultFixed();
            m_antiVirusWork->sendNotifyUpdateAntiVirusHomeUI();
            m_antiVirusWork->setCurrentScanStatus(ScanStatus::Free);
        }
    }
}

// 修复首页体检快速病毒扫描的结果
void HomePageModel::FixHomepageVirusScanResult()
{
    // 修复病毒中
    m_antiVirusWork->setCurrentScanStatus(ScanStatus::HomePageFixing);
    for (QString path : m_virusPathList) {
        m_antiVirusWork->requestRepairProblemFile(path);
    }
}

// 停止快速病毒扫描
void HomePageModel::stopVirusQuickScan()
{
    // 当处于首页病毒扫描 和 首页扫描结果 时，设置扫描状态为空闲
    ScanStatus status = m_antiVirusWork->getCurrentScanStatus();
    if (ScanStatus::HomePageScanning == status
        || ScanStatus::HomePageResult == status
        || ScanStatus::HomePageFixing == status) {
        m_antiVirusWork->setCurrentScanStatus(ScanStatus::Free);
    }
}

// 更新自启动应用个数
void HomePageModel::updateStartUpAppCount(bool bAdd, const QString &sID)
{
    Q_UNUSED(bAdd);
    Q_UNUSED(sID);
//    QtConcurrent::run([this] {
//        // 判断自启动应用个数
        int count = getAutoStartAppCount();
        Q_EMIT autoStartAppCountChanged(count);
//    });
}

void HomePageModel::onTrashScanFinished(double sum)
{
    Q_EMIT trashScanFinished(sum);
}

void HomePageModel::checkAutoStart()
{
//    QtConcurrent::run([this] {
        int nEnableCount = getAutoStartAppCount();
        // 若当前正在检查自启动
        if (m_autoStartAppChecking) {
            Q_EMIT checkAutoStartFinished(nEnableCount);
        }
//    });
}

bool HomePageModel::ignoreAutoStartChecking() const
{
    return m_gSettingsInvokerInter->GetValue(IGNORE_AUTO_START_CHECKING).toBool();
}

void HomePageModel::setIgnoreAutoStartChecking(bool ignore)
{
    m_gSettingsInvokerInter->SetValue(IGNORE_AUTO_START_CHECKING, ignore);
}

// 异步获取ssh状态
void HomePageModel::asyncGetSSHStatus() const
{
    DBUS_BLOCK_INVOKE(m_netFlowMonitorInvokerInter, "AsyncGetRemRegisterStatus");
}

void HomePageModel::asyncSetSSHStatus(bool status)
{
    DBUS_BLOCK_INVOKE(m_netFlowMonitorInvokerInter, "AsyncSetRemRegisterStatus", status);
}

// 获取允许自启动应用个数
int HomePageModel::getAutoStartAppCount() const
{
    int nEnableCount = 0;
    QDBusMessage msg = DBUS_BLOCK_INVOKE(m_defenderDataInvokerInter, "startLauncherManage");
    GET_MESSAGE_VALUE(bool, success, msg);
    if (success) {
        QDBusMessage msg = DBUS_BLOCK_INVOKE(m_defenderDataInvokerInter, "getAppsInfoEnable");
        GET_MESSAGE_VALUE(QString, sEnableInfo, msg);
        QApplication::processEvents();
        if (!sEnableInfo.isEmpty())
            nEnableCount = sEnableInfo.split("|").count();
    }

    return nEnableCount;
}

// 添加安全日志
void HomePageModel::addSecurityLog(QString sInfo)
{
    DBUS_NOBLOCK_INVOKE(m_netFlowMonitorInvokerInter, "AddSecurityLog", SECURITY_LOG_TYPE_HOME, sInfo);
}

void HomePageModel::onRequestStartTrashScan()
{
    DBUS_NOBLOCK_INVOKE(m_defenderDataInvokerInter, "RequestStartTrashScan");
}

void HomePageModel::onRequestCleanSelectTrash()
{
    DBUS_NOBLOCK_INVOKE(m_defenderDataInvokerInter, "RequestCleanSelectTrash");
}
